<!DOCTYPE html>
<html>
  <head>
    <title>111</title>
  </head>
  <body>
    <style>
      .btn {
        outline: none;
        border: none;
        cursor: pointer;
        padding: 5px 12px;
      }
      .btn-text {
        color: #409eff;
        background-color: transparent;
      }
      .btn-text:hover {
        color: #66b1ff;
      }
    </style>
    <div id="app">
      <!-- 将实例中 fields & goods 传入组件 -->
      <fly-table :fields="fields" :goods="goods">
        <span slot="title">Fly Table Component</span>
      </fly-table>
    </div>
    <script src="https://cdn.jsdelivr.net/npm/vue@2.5.16/dist/vue.js"></script>
    <script type="text/javascript">
      Vue.component("fly-table", {
        props: {
          // 组件接收外界传入的参数
          fields: {
            type: Array,
            default() {
              return [];
            }
          },
          goods: {
            type: Array,
            default() {
              return [];
            }
          }
        },
        methods: {
          reverse() {
            // 定义数组倒序方法
            this.goods.reverse();
          }
        },
        render(createElement) {
          // 使用render函数渲染DOM
          /**
           * createElement 可接收三个参数
           * 1. HTML标签字符串（String）| 组件选项对象（Object）| 节点解析函数（Function）
           * 2. 定义节点特性的对象（Object）
           * 3. 子节点，createElement构建的VNode节点或字符串生成的无标签文本节点（Array|String）
           */
          return createElement(
            "div",
            {
              // * 作为子组件时的插槽名称
              slot: "fly-table"
            },
            [
              createElement("h2", this.$slots.title),
              createElement("button", {
                // class 用于绑定类名，同v-bind:class的绑定方式
                class: ["btn", "btn-text"],
                style: {
                  color: 'red'
                },
                // attrs 用于绑定节点一般属性，如id、disabled、title等
                attrs: {
                  disabled: false,
                  title: "点击使数组倒序"
                },
                // domProps 用于绑定节点DOM属性，如innerHTML、innerText等
                domProps: {
                  innerText: "倒序"
                },
                on: {
                  // 绑定事件，使用箭头函数以免创建函数作用域
                  click: () => {
                    this.goods.reverse();
                  }
                },
                // 自定义指令
                directives: [],
                // 其他属性
                key: "btnReverse",
                ref: "btnReverse"
              }),
              createElement(
                "table",
                {
                  // style 用于绑定样式，同v-bind:style的绑定方式
                  style: {
                    width: "400px",
                    textAlign: "left",
                    lineHeight: "42px",
                    border: "1px solid #eee",
                    userSelect: "none" //控制能够选择文本
                  }
                },
                [
                  createElement("tr", [
                    this.fields.map(field => createElement("th", field.prop))
                  ]),
                  this.goods.map(item =>
                    createElement(
                      "tr",
                      {
                        style: {
                          color: item.isMarked ? "#ea4335" : ""
                        }
                      },
                      this.fields.map(field =>
                        createElement(
                          "td",
                          {
                            style: {
                              borderTop: "1px solid #eee"
                            }
                          },
                          [
                            field.prop !== "operate" // 如果不是操作列，显示文本  判断是生成span还是button
                              ? createElement("span", item[field.prop])
                              : createElement("button", {
                                  // 否则显示按钮
                                  class: ["btn", "btn-text"],
                                  domProps: {
                                    innerHTML: "<span>切换标记</span>"
                                  },
                                  on: {
                                    click: () => {
                                      // 当按钮被点击时，切换该行文本标记状态（被标记时字体颜色为红色）
                                      item.isMarked = !item.isMarked;
                                    }
                                  }
                                })
                          ]
                        )
                      )
                    )
                  )
                ]
              )
            ]
          );
        }
      });
      // 声明 Vue 实例
      new Vue({
        el: "#app",
        data() {
          return {
            fields: [
              {
                label: "名称",
                prop: "name"
              },
              {
                label: "数量",
                prop: "quantity"
              },
              {
                label: "价格",
                prop: "price"
              },
              {
                label: "",
                prop: "operate"
              }
            ],
            goods: [
              {
                name: "苹果",
                quantity: 200,
                price: 6.8,
                isMarked: false
              },
              {
                name: "西瓜",
                quantity: 50,
                price: 4.8,
                isMarked: false
              },
              {
                name: "榴莲",
                quantity: 0,
                price: 22.8,
                isMarked: false
              }
            ]
          };
        }
      });
    </script>
  </body>
</html>
